package com.fingard.dsp.bank.directbank.ybt13;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.*;
import com.fingard.text.StringHelper;

import java.io.BufferedReader;
import java.io.File;
import java.io.StringReader;
import java.text.MessageFormat;


public class YBT13BatPayRec extends YBT13Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            // 代收付文件内容
            StringBuilder sbFileContent = new StringBuilder();
            String bankCode = getBankConfig().getMapValueByKey("bankCodeMapping", p_reqBat.ownAct);
            if (StringHelper.isNullOrEmpty(bankCode)) {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号" + p_reqBat.ownAct + "的银行代码映射，请检查YBT13/config.xml中'bankCodeMapping'节点配置";
                return retAts;
            }
            String transType = "S";
            if ("1988".equals(p_reqBat.reqHeader.transType)) {
                transType = "F";
            }
            String tmpPayDate = Format.Date8Format.format(p_reqBat.getPayDateTime());//交易日期

            // 文件头  银行代码|交易类型(S-代收、F-代付)|交易日期|交易批次号|交易总笔数|交易总金额|备注1|备注2|备注3|备注4|备注5
            String tmpReqHeader = MessageFormat.format("{0}|{1}|{2}|{3}|{4}|{5}|||||\n", bankCode, transType, tmpPayDate, p_reqBat.reqBatchNO, p_reqBat.totalNum, p_reqBat.totalAmt);
            sbFileContent.append(tmpReqHeader);

            while (p_reqBat.readRecord()) {
                String askNumber = p_reqBat.readedDetail.askNumber;
                String tmpCertType = getBankConfig().getMapValueByKey("certTypeMapping", p_reqBat.readedDetail.certType);
                String tmpCertNum = p_reqBat.readedDetail.certNum;
                String certType = "";
                String certNum = "";
                //证件类型、证件号码必须同时为空或者同时有值
                if (StringHelper.hasAnyChar(tmpCertType) && StringHelper.hasAnyChar(tmpCertNum)) {
                    certType = tmpCertType;
                    certNum = tmpCertNum;
                }
                String cardType = getBankConfig().getMapValueByKey("cardTypeMapping", p_reqBat.readedDetail.cardType);
                String oppAct = p_reqBat.readedDetail.payAct;
                String oppName = p_reqBat.readedDetail.payName;
                String payAmount = p_reqBat.readedDetail.payAmount;
                String payCur = getBankConfig().getMapValueByKey("currencyMapping", p_reqBat.readedDetail.payCur);
                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    oppAct = p_reqBat.readedDetail.recAct;
                    oppName = p_reqBat.readedDetail.recName;
                }
                String sourceNoteCode = p_reqBat.readedDetail.sourceNoteCode;
                // 交易明细序号|证件类型|证件号码|客户银行账户类型|客户银行帐号|客户姓名|金额|业务类型|业务号码|币种|备注1|备注2|备注3备注4|备注5|备注6
                String tmpReqBodyDetail = MessageFormat.format("{0}|{1}|{2}|{3}|{4}|{5}|{6}||{7}|{8}||||||\n", askNumber, certType, certNum, cardType, oppAct, oppName, payAmount, sourceNoteCode, payCur);
                sbFileContent.append(tmpReqBodyDetail);
            }

            String tmpReqData = sbFileContent.toString();
            WriteBankLogLn2("批次请求文件内容：" + tmpReqData);

            // 文件名称：银行代码_交易日期_交易类型(S-代收、F-代付)_交易批次号.txt
            String tmpUpFileName = bankCode + "_" + tmpPayDate + "_" + transType + "_" + p_reqBat.reqBatchNO + ".txt";
            String tmplocalFilePath = createTempFileDirectory(tmpPayDate) + File.separator + "upload" + File.separator + tmpUpFileName;
            WriteBankLogLn2("批次请求文件保存本地路径:" + tmplocalFilePath);
            if (FileHelper.existFile(tmplocalFilePath)) {
                retAts.respCode = "0";
                retAts.respInfo = "本地批次文件已上传,请勿重复上传!";
                retAts.reqSeqID = p_reqBat.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }
            FileHelper.writeFile(tmplocalFilePath, tmpReqData, getCharset());

            //上送银保通服务器
            String upDir = "/Fund" + "/" + bankCode + "/" + "Send" + "/" + tmpPayDate;
            FtpSet ftpSet = bankFront.getFtpSet("bat");
            MixFtp mixFtp = new MixFtp(ftpSet);
            FtpReceiver ftpReceiver = mixFtp.uploadFileToDir(tmplocalFilePath, upDir, tmpUpFileName);

            retAts.respCode = "0";
            if (!ftpReceiver.isCompleted) {
                retAts.respCode = "-1";
                retAts.respInfo = ftpReceiver.connMsg;
            } else if (ConnState.FAIL.equals(ftpReceiver.connState)) {
                retAts.respInfo = "上传失败";
                retAts.transState = "BatchFailed";
                retAts.payInfoCode = "E9999";
            } else {
                retAts.respInfo = "上传成功";
                retAts.transState = "Uploaded";
                retAts.payInfoCode = "I4001";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

        try {
            String bankCode = getBankConfig().getMapValueByKey("bankCodeMapping", p_reqQryBat.ownAct);
            if (StringHelper.isNullOrEmpty(bankCode)) {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号" + p_reqQryBat.ownAct + "的银行代码映射，请检查YBT13/config.xml中'bankCodeMapping'节点配置";
                return retAts;
            }
            String tmpPaySendDate = Format.Date8Format.format(p_reqQryBat.getBgnDateTime());
            String transType = "S";
            if ("1998".equalsIgnoreCase(p_reqQryBat.reqHeader.transType)) {
                transType = "F";
            }
            // 文件名称：银行代码_交易日期_交易类型(S-代收、F-代付)_交易批次号.txt
            String tmpDownFileName = bankCode + "_" + tmpPaySendDate + "_" + transType + "_" + p_reqQryBat.reqBatchNO + ".txt";
            String tmpLocalMarkPath = createTempFileDirectory(tmpPaySendDate) + File.separator + "download" + File.separator + tmpDownFileName;
            WriteBankLogLn2("批次结果文件保存本地路径: " + tmpLocalMarkPath);


            String downDir = "/Fund" + "/" + bankCode + "/" + "Get" + "/" + tmpPaySendDate;
            FtpSet ftpSet = bankFront.getFtpSet("bat");
            MixFtp mixFtp = new MixFtp(ftpSet);
            FtpReceiver ftpReceiver = mixFtp.downloadFileFromDir(downDir, tmpDownFileName, tmpLocalMarkPath);
            if (ftpReceiver.isCompleted) {
                String tmpStrRet = FileHelper.readFileText(tmpLocalMarkPath, getCharset());
                WriteBankLogLn2("本地批次结果文件内容:\r\n" + tmpStrRet);
                if (StringHelper.hasAnyChar(tmpStrRet)) {
                    retAts.respCode = "0";
                    StringReader strReader = new StringReader(tmpStrRet);
                    BufferedReader tmpReader = new BufferedReader(strReader);
                    tmpReader.readLine();

                    while (true) {
                        String eachline = tmpReader.readLine();
                        if (StringHelper.isNullOrEmpty(eachline)) {
                            break;
                        }
                        if (eachline.indexOf("|") > 0) {
                            String[] bodyValues = eachline.split("\\|");
                            //首行内容：
                            //银行代码|交易类型(S-代收、F-代付)|交易日期|交易批次号|交易总笔数|交易总金额|交易成功总笔数|交易成功总金额|备注1|备注2|备注3|备注4|备注5
                            //明细行内容：
                            //交易明细序号|客户银行帐号|客户姓名|金额(元，两位小数)|证件类型|证件号码|业务类型|交易状态|交易结果代码|交易结果信息|备注1|备注2|备注3|备注4|备注5|备注6
                            RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();
                            tmpRetDetail.postScript = bodyValues[0];
                            tmpRetDetail.payAmount = bodyValues[3];
                            if ("9198".equalsIgnoreCase(p_reqQryBat.reqHeader.transType)) {
                                tmpRetDetail.payAct = bodyValues[1];
                                tmpRetDetail.payName = bodyValues[2];
                            } else {
                                tmpRetDetail.recAct = bodyValues[1];
                                tmpRetDetail.recName = bodyValues[2];
                            }
                            tmpRetDetail.result = bodyValues[7];
                            tmpRetDetail.payInfoCode = bodyValues[8];
                            tmpRetDetail.memo = bodyValues[9];
                            retAts.writeRetDetail(tmpRetDetail);
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = "银行返回明细数据格式非法!";
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "本地批次结果文件内容为空!";
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "批次结果文件下载失败:" + ftpReceiver.connMsg;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}